package com.cmccsi.webservice;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.cmccsi.entity.qxdeptDto;
import com.cmccsi.entity.qxdomainDto;
import com.cmccsi.entity.qxuserDto;
import com.cmccsi.service.impl.DeptServiceImpl;
import com.cmccsi.service.impl.DomainServiceImpl;
import com.cmccsi.service.impl.QxUserServiceImpl;
import com.huawei.eidc.slee.security.DESTools;
import com.huawei.eidc.slee.security.MD5;

public class ADCHandlFactory implements IADCHandlFactory {

	private static final String CorpBindRsp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
			+ "<CorpBindRsp>"
			+ "<HEAD>"
			+ "<CODE>%s</CODE>"
			+ "<SID>%s</SID>"
			+ "<TIMESTAMP>%s</TIMESTAMP>"
			+ "<SERVICEID>%s</SERVICEID>"
			+ "</HEAD>" + "<BODY>%s</BODY>" + "</CorpBindRsp>";

	private static final String CorpBindRspBody = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
			+ "<BODY>"
			+ "<RESULTCODE>%s</RESULTCODE>"
			+ "<RESULTMSG>%s</RESULTMSG>" + "<URL>%s</URL>" + "</BODY>";

	private static final String StaffBindRsp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
			+ "<StaffBindRsp>"
			+ "<HEAD>"
			+ "<CODE>%s</CODE>"
			+ "<SID>%s</SID>"
			+ "<TIMESTAMP>%s</TIMESTAMP>"
			+ "<SERVICEID>%s</SERVICEID>"
			+ "</HEAD>" + "<BODY>%s</BODY>" + "</StaffBindRsp>";

	private static final String StaffBindRspBody = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
			+ "<BODY>"
			+ "<CORPACCOUNT>%s</CORPACCOUNT>"
			+ "<STAFFLIST>%s"
			+ "</STAFFLIST>" + "</BODY>";

	private static final String StaffBindRspUserBody = "<STAFFINFO>"
			+ "<UFID>%s</UFID>" + "<STAFFNAME>%s</STAFFNAME>"
			+ "<STAFFMOBILE>%s</STAFFMOBILE>" + "<RESULTCODE>%s</RESULTCODE>"
			+ "<RESULTMSG>%s</RESULTMSG>" + "</STAFFINFO>";

	private String deskey = "20CC094C6E30FF5C";
	public Logger loger = Logger.getLogger(ADCHandlFactory.class);

	@Override
	public String AnalyseCorpBind(String CorpBindReq) {
		// TODO Auto-generated method stub
		loger.info(CorpBindReq);
		int res_code = 0;
		// TODO Auto-generated method stub
		// System.out.println("这里是服务端,接收到了传来的数据" + CorpBindReq);
		if (CorpBindReq.isEmpty()) {
			// @todo:处理提交参数错误后的返回值
			loger.error("请求参数CorpBindReq为空");
			return "";
		}

		try {
			DESTools des = DESTools.getInstance(deskey);
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			InputStream inps = new ByteArrayInputStream(
					CorpBindReq.getBytes("UTF-8"));
			Document doc = builder.parse(inps);

			String strBODY = doc.getElementsByTagName("BODY").item(0)
					.getTextContent();
			String strCODE = doc.getElementsByTagName("CODE").item(0)
					.getTextContent();
			String strSID = doc.getElementsByTagName("SID").item(0)
					.getTextContent();
			String strTIMESTAMP = doc.getElementsByTagName("TIMESTAMP").item(0)
					.getTextContent();
			String strSERVICEID = doc.getElementsByTagName("SERVICEID").item(0)
					.getTextContent();
			String msgDecrypted = new String(des.decrypt(strBODY
					.getBytes("UTF-8")));

			loger.info(msgDecrypted);
			String strMsgExcMd5 = msgDecrypted.substring(32);// 去掉前面md5的32位

			InputStream inpsBody = new ByteArrayInputStream(
					strMsgExcMd5.getBytes("UTF-8"));
			Document docBody = builder.parse(inpsBody);

			String OPTYPE = docBody.getElementsByTagName("OPTYPE").item(0)
					.getTextContent();
			int OPTYPENum = Integer.parseInt(OPTYPE);
			/*
			 * 1 : 订购；2 : 暂停；3 : 恢复；4 : 变更 5 :
			 * 退订（要求SI系统自动取消相应的员工的定购关系）；6：企业基本信息变更 状态2、3、5只用集团客户名称和集团客户帐号字段
			 */

			String action = "";
			int status = 0;
			switch (OPTYPENum) {
			case 1:
				action = "insert";
				break;
			case 2:
				action = "update";
				status = 0;
				break;
			case 3:
				status = 1;
				action = "update";
				break;
			case 4:
				action = "update_data";
				break;
			case 5:
				action = "delete";
				break;
			case 6:
				action = "update_data";
				break;
			default:
				break;
			}

			String domain = docBody.getElementsByTagName("CORPACCOUNT").item(0)
					.getTextContent();
			String domain_name = docBody.getElementsByTagName("CORPNAME")
					.item(0).getTextContent();
			String license = docBody.getElementsByTagName("LICENSE").item(0)
					.getTextContent();

			if (domain.isEmpty() || domain_name.isEmpty()) {
				loger.error("domain或者domain_name为空");
				res_code = 404;
				return MakeCorpBindRsp(
						strCODE,
						strSID,
						strSERVICEID,
						MakeCorpBindRspBody(Integer.toString(res_code),
								"绑定失败,domain或者domain_name为空", ""));
			}

			String paramname = "";// 业务配置参数名称
			String paramvalue = "";// 业务配置参数值

			String corpinfoname = "";// 企业信息参数名称
			String corpinfovalue = "";// 企业信息参数值

			String pointname = "";// 订购功能点参数名称
			String pointvalue = "";// 订购功能点参数值

			NodeList nodlst = docBody.getElementsByTagName("PARAMMAP");

			if (nodlst != null && nodlst.getLength() > 0) {
				for (int i = 0; i < nodlst.getLength(); i++) {

					Node nd = nodlst.item(i).getFirstChild();
					if (nd.getNodeName().toUpperCase() == "PARAMNAME") {
						paramname += nd.getTextContent() + ",";
					} else if (nd.getNodeName().toUpperCase() == "PARAMVALUE") {
						paramvalue += nd.getTextContent() + ",";
					}
				}
			}

			nodlst = docBody.getElementsByTagName("CORPINFOMAP");

			if (nodlst != null && nodlst.getLength() > 0) {
				for (int i = 0; i < nodlst.getLength(); i++) {
					Node nd = nodlst.item(i).getFirstChild();
					if (nd.getNodeName().toUpperCase() == "CORPINFONAME") {
						corpinfoname += nd.getTextContent() + ",";
					} else if (nd.getNodeName().toUpperCase() == "CORPINFOVALUE") {
						corpinfovalue += nd.getTextContent() + ",";
					}
				}
			}

			nodlst = docBody.getElementsByTagName("ORDERPOINTMAP");

			if (nodlst != null && nodlst.getLength() > 0) {
				for (int i = 0; i < nodlst.getLength(); i++) {

					Node nd = nodlst.item(i).getFirstChild();
					if (nd.getNodeName().toUpperCase() == "POINTNAME") {
						pointname += nd.getTextContent() + ",";
					} else if (nd.getNodeName().toUpperCase() == "POINTVALUE") {
						pointvalue += nd.getTextContent() + ",";
					}
				}
			}

			paramname = paramname.substring(0, paramname.length() > 254 ? 254
					: paramname.length());
			paramvalue = paramvalue.substring(0,
					paramvalue.length() > 254 ? 254 : paramvalue.length());

			corpinfoname = corpinfoname.substring(0,
					corpinfoname.length() > 254 ? 254 : corpinfoname.length());
			corpinfovalue = corpinfovalue
					.substring(0, corpinfovalue.length() > 254 ? 254
							: corpinfovalue.length());

			pointname = pointname.substring(0, pointname.length() > 254 ? 254
					: pointname.length());
			pointvalue = pointvalue.substring(0,
					pointvalue.length() > 254 ? 254 : pointvalue.length());

			DomainServiceImpl domainSrv = new DomainServiceImpl();

			qxdomainDto domainDto = new qxdomainDto();

			domainDto.setDomain(domain);

			domainDto.setDomainName(domain_name);

			domainDto.setLicense(Integer.parseInt(license));

			domainDto.setCorpinfoname(corpinfoname);
			domainDto.setCorpinfovalue(corpinfovalue);
			domainDto.setParamname(paramname);
			domainDto.setParamvalue(paramvalue);
			domainDto.setPointname(pointname);
			domainDto.setPointvalue(pointvalue);

			if (action == "insert") {
				domainDto.setCyloginflag(1);
				Boolean r = domainSrv.save(domainDto);
				Boolean rd = false;
				if (r) {
					DeptServiceImpl dptSrv = new DeptServiceImpl();

					qxdeptDto dpt = new qxdeptDto();

					dpt.setName(domain_name);

					dpt.setParentId((long) 0);

					dpt.setDomainid(domain);
					rd = dptSrv.save(dpt);
					if (rd) {
						return MakeCorpBindRsp(strCODE, strSID, strSERVICEID,
								MakeCorpBindRspBody("0", "绑定成功", ""));
					}

				}
				if (!(r & rd)) {
					return MakeCorpBindRsp(strCODE, strSID, strSERVICEID,
							MakeCorpBindRspBody("404", "绑定失败", ""));
				}

			} else if (action == "update") {
				domainDto.setCyloginflag(status);
				Boolean r = domainSrv.save(domainDto);
				if (r) {
					return MakeCorpBindRsp(strCODE, strSID, strSERVICEID,
							MakeCorpBindRspBody("0", "绑定成功", ""));
				} else {
					return MakeCorpBindRsp(strCODE, strSID, strSERVICEID,
							MakeCorpBindRspBody("404", "绑定失败", ""));
				}

			} else if (action == "delete") {

				Boolean r = domainSrv.delete(domain);
				if (r) {
					return MakeCorpBindRsp(strCODE, strSID, strSERVICEID,
							MakeCorpBindRspBody("0", "绑定成功", ""));
				} else {
					return MakeCorpBindRsp(strCODE, strSID, strSERVICEID,
							MakeCorpBindRspBody("404", "绑定失败", ""));
				}
			} else if (action == "update_data") {
				Boolean r = domainSrv.update(domainDto);
				if (r) {
					return MakeCorpBindRsp(strCODE, strSID, strSERVICEID,
							MakeCorpBindRspBody("0", "绑定成功", ""));
				} else {
					return MakeCorpBindRsp(strCODE, strSID, strSERVICEID,
							MakeCorpBindRspBody("404", "绑定失败", ""));
				}
			}

			// domainSrv

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			loger.error(e.getMessage(),e);
		}

		return "";
	}

	@Override
	public String AnalyseStaffBind(String StaffBindReq) {
		// TODO Auto-generated method stub
		int res_code = 0;
		// TODO Auto-generated method stub
		// System.out.println("这里是服务端,接收到了传来的数据" + CorpBindReq);
		if (StaffBindReq.isEmpty()) {
			// @todo:处理提交参数错误后的返回值
			loger.error("请求参数StaffBindReq为空");
			return "";
		}
		QxUserServiceImpl QxUsrSrv = new QxUserServiceImpl();
		try {
			DESTools des = DESTools.getInstance(deskey);
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			InputStream inps = new ByteArrayInputStream(
					StaffBindReq.getBytes("UTF-8"));
			Document doc = builder.parse(inps);

			String strBODY = doc.getElementsByTagName("BODY").item(0)
					.getTextContent();
			String strCODE = doc.getElementsByTagName("CODE").item(0)
					.getTextContent();
			String strSID = doc.getElementsByTagName("SID").item(0)
					.getTextContent();
			String strTIMESTAMP = doc.getElementsByTagName("TIMESTAMP").item(0)
					.getTextContent();
			String strSERVICEID = doc.getElementsByTagName("SERVICEID").item(0)
					.getTextContent();
			String msgDecrypted = new String(des.decrypt(strBODY
					.getBytes("UTF-8")));

			loger.info(msgDecrypted);
			String strMsgExcMd5 = msgDecrypted.substring(32);// 去掉前面md5的32位

			InputStream inpsBody = new ByteArrayInputStream(
					strMsgExcMd5.getBytes("UTF-8"));
			Document docBody = builder.parse(inpsBody);

			String domain = docBody.getElementsByTagName("CORPACCOUNT").item(0)
					.getTextContent();// //企业编号
			DomainServiceImpl domainSrv = new DomainServiceImpl();
			qxdomainDto domainDTO = domainSrv.find(domain);
			if (domain.isEmpty() || domainDTO != null)/* 错误判断：集团账号判断 */
			{
				res_code = 501;
				return MakeStaffBindRsp(strCODE, strSID, strSERVICEID,
						strMsgExcMd5);
			} else {
				NodeList nodlst = docBody.getElementsByTagName("STAFFINFO");
				String UFID = "";
				String USERTYPE = "";
				String STAFFNAME = "";
				String STAFFMOBILE = "";
				int OPTYPE = 0;
				String action = "";
				int status = 0;
				List<UserActionResult> lstUsrAction = new ArrayList<UserActionResult>();
				if (nodlst != null && nodlst.getLength() > 0) {
					for (int i = 0; i < nodlst.getLength(); i++) {
						UFID = "";
						USERTYPE = "";
						STAFFNAME = "";
						STAFFMOBILE = "";
						OPTYPE = 0;
						action = "";
						NodeList nodlstCld = nodlst.item(i).getChildNodes();
						for (int j = 0; j < nodlstCld.getLength(); j++) {
							Node nd = nodlst.item(i);
							if (nd.getNodeName().toUpperCase() == "UFID") {
								UFID = nd.getTextContent();
							} else if (nd.getNodeName().toUpperCase() == "USERTYPE") {
								USERTYPE = nd.getTextContent();
							} else if (nd.getNodeName().toUpperCase() == "STAFFNAME") {
								STAFFNAME = nd.getTextContent();
							} else if (nd.getNodeName().toUpperCase() == "STAFFMOBILE") {
								STAFFMOBILE = nd.getTextContent();
							} else if (nd.getNodeName().toUpperCase() == "OPTYPE") {
								OPTYPE = Integer.parseInt(nd.getTextContent());
							}

						}

						switch (OPTYPE) {
						case 1:
							action = "insert";
							break;
						case 2:
							status = 0;// 暂停是0
							action = "update";
							break;
						case 3:
							status = 1;// 恢复是1
							action = "update";
							break;
						case 4:
							action = "update_data";// 恢复是1
							break;
						case 5:
							action = "delete";// 退订
							break;
						}
						UserActionResult usr = new UserActionResult();
						qxuserDto usrDto = new qxuserDto();
						usrDto.setAuth("123456");
						usrDto.setMobilePhone(STAFFMOBILE);
						usrDto.setUserName(STAFFNAME);
						usrDto.setDisplayName(STAFFNAME);
						usrDto.setDomainid(domain);
						// 后面再行处理 UFID和USERTYPE
						usr.setUser(usrDto);
						Boolean r = false;
						if (STAFFMOBILE.length() < 11) {
							usr.setRESULTCODE("502");
							usr.setRESULTMSG("用户手机号码非法");
							lstUsrAction.add(usr);
						} else {
							if (action == "insert") {
								usrDto.setCyloginflag(1);
								r = QxUsrSrv.save(usrDto,0);
							} else if (action == "update") {
								usrDto.setCyloginflag(status);
								r = QxUsrSrv.save(usrDto,0);
							} else if (action == "delete") {
								r = QxUsrSrv.deleteByMobile(usrDto
										.getMobilePhone());
							} else if (action == "update_data") {
								usrDto.setCyloginflag(status);
								r = QxUsrSrv.save(usrDto,0);
							}
						}
						usr.setUser(usrDto);
						if (r) {
							usr.setRESULTCODE("0");
							usr.setRESULTMSG("成功");
						} else {
							usr.setRESULTCODE("1");
							usr.setRESULTMSG("企信用户数据更新错误");
						}
						lstUsrAction.add(usr);
					}

					String staffBindRspUserBody = "";
					staffBindRspUserBody = MakeStaffBindRspBody(domain,
							lstUsrAction);
					return MakeStaffBindRsp(strCODE, strSID, strSERVICEID,
							staffBindRspUserBody);

				} else {
					return MakeStaffBindRsp(strCODE, strSID, strSERVICEID, "");
					// 绑定员工数据为空 暂不处理
				}
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			loger.error(e.getMessage(),e);  
		}

		return "";
	}

	private String MakeCorpBindRsp(String CODE, String SID, String SERVICEID,
			String Body) {
		if (Body.isEmpty() || CODE.isEmpty() || SERVICEID.isEmpty())
			return "";
		String CorpBindRspTmp = CorpBindRsp;
		loger.info("MakeCorpBindRsp 加密前：" + Body);

		try {
			String TIMESTAMP = new SimpleDateFormat("yyyMMddHHmmssSSSS")
					.format(new Date());
			DESTools des = DESTools.getInstance(deskey);
			String tempBody = MD5.md5(Body) + Body;
			String desBody = new String(des.encrypt(tempBody.getBytes("UTF-8")));
			String.format(CorpBindRspTmp, CODE, SID, TIMESTAMP, SERVICEID,
					desBody);

			return CorpBindRspTmp;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 

		return "";
	}

	private String MakeCorpBindRspBody(String RESULTCODE, String RESULTMSG,
			String URL) {
		String CorpBindRspBodyTmp = CorpBindRspBody;
		String.format(CorpBindRspBodyTmp, RESULTCODE, RESULTMSG, URL);

		return CorpBindRspBodyTmp;
	}

	private String MakeStaffBindRsp(String CODE, String SID, String SERVICEID,
			String ReturnBody) {
		if (ReturnBody.isEmpty() || CODE.isEmpty() || SERVICEID.isEmpty())
			return "";
		String StaffBindRspTmp = StaffBindRsp;
		String TIMESTAMP = new SimpleDateFormat("yyyMMddHHmmssSSSS")
				.format(new Date());

		loger.info("MakeStaffBindRsp 加密前：" + ReturnBody);

		try {
			DESTools des = DESTools.getInstance(deskey);
			String tempBody = MD5.md5(ReturnBody) + ReturnBody;
			String desBody = new String(des.encrypt(tempBody.getBytes("UTF-8")));
			String.format(StaffBindRspTmp, CODE, SID, TIMESTAMP, SERVICEID,
					desBody);

			return StaffBindRspTmp;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// todo:ReturnBody 加密
		return "";

	}

	private String MakeStaffBindRspBody(String CORPACCOUNT,
			List<UserActionResult> users) {
		if (CORPACCOUNT.isEmpty() || users == null)
			return "";

		String StaffBindRspBodyTmp = StaffBindRspBody;

		String StaffBindRspUserBody = "";
		for (UserActionResult userActionResult : users) {
			StaffBindRspUserBody += MakeStaffBindRspUserBody(userActionResult);
		}
		String.format(StaffBindRspBodyTmp, CORPACCOUNT, StaffBindRspUserBody);

		return "";
	}

	private String MakeStaffBindRspUserBody(UserActionResult user) {
		if (user == null)
			return "";
		String strStaffBindRspUserBodyTmp = StaffBindRspUserBody;

		qxuserDto qxuser = user.getUser();
		String.format(strStaffBindRspUserBodyTmp, qxuser.getId(),
				qxuser.getUserName(), qxuser.getMobilePhone(),
				user.getRESULTCODE(), user.getRESULTMSG());

		return strStaffBindRspUserBodyTmp;
	}

}
